﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Integrate.Window.UI
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:Integrate.Window.UI"
    ///
    ///
    /// Step 1b) Using this custom control in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:Integrate.Window.UI;assembly=Integrate.Window.UI"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your control in the XAML file.
    ///
    ///     <MyNamespace:StateButton/>
    ///
    /// </summary>
    public class StateButton : Button
    {
        #region Constructors
        static StateButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(StateButton), new FrameworkPropertyMetadata(typeof(StateButton)));
        }
        #endregion

        #region Routed Event

        #region Powered On Event
        /// <summary>
        /// When property IsStateEnable is True, Control will be raised PowerdOnEvent
        /// </summary>
        public static readonly RoutedEvent PoweredOnEvent =
            EventManager.RegisterRoutedEvent("PowerOn",
                RoutingStrategy.Bubble,
                typeof(RoutedEventHandler),
                typeof(StateButton));

        /// <summary>
        /// Add / Remove PowerOnEvent handler
        /// </summary>
        public event RoutedEventHandler PoweredOn 
        {
            add { AddHandler(PoweredOnEvent, value); }
            remove { RemoveHandler(PoweredOnEvent, value); }
        }
        #endregion

        #region Powered Off Event
        /// <summary>
        /// When property IsStateEnable is False, Control will be raised PowerdOffEvent
        /// </summary>
        public static readonly RoutedEvent PoweredOffEvent =
            EventManager.RegisterRoutedEvent("PowerOff",
                RoutingStrategy.Bubble,
                typeof(RoutedEventHandler),
                typeof(StateButton));

        /// <summary>
        /// Add / Remove PowerOnEvent handler
        /// </summary>
        public event RoutedEventHandler PoweredOff
        {
            add { AddHandler(PoweredOffEvent, value); }
            remove { RemoveHandler(PoweredOffEvent, value); }
        }
        #endregion

        #endregion

        #region Dependency Properties
        #region IsStateEnable
        /// <summary>
        /// IsStateEnable is used to store state. When it is Changed, buttonControl will start the corresponding animation according to its value
        /// </summary>
        public bool IsStateEnable
        {
            get { return (bool)GetValue(IsPoweredOnProperty); }
            set { SetValue(IsPoweredOnProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsPoweredOn.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsPoweredOnProperty =
            DependencyProperty.Register("IsStateEnable", typeof(bool), typeof(StateButton), new PropertyMetadata(false, StateValueChanged));
        #endregion

        #endregion
        #region Private Static Function CallBack
        /// <summary>
        /// IsStateEnable property changed, Applicaiton call back this funciton.
        /// </summary>
        /// <param name="d">Event Sender a IsStateEnable property owner</param>
        /// <param name="e">Event argments</param>
        private static void StateValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ctr = d as StateButton;
            var oldValue = (bool)e.OldValue;
            var newValue= (bool)e.NewValue;

            if(oldValue!=newValue)
            {
                if(newValue)
                {
                    ctr.RaiseEvent(new RoutedEventArgs(PoweredOnEvent, ctr));
                }
                else
                {
                    ctr.RaiseEvent(new RoutedEventArgs(PoweredOffEvent, ctr));
                }
            }
            // else nothing
        }
        #endregion
    }
} 
